﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using YArchitech.Revit;

namespace YJKArchMethodLibrary.Utils
{
	public class FindWallsByColumnKit
	{
		public FindWallsByColumnKit(UIApplication uiApp)
		{
			this.m_uiApplication = uiApp;
			this.m_document = this.m_uiApplication.ActiveUIDocument.Document;
		}

		public Dictionary<int, List<Wall>> GetWallListByColumn()
		{
			Dictionary<int, List<Wall>> result = new Dictionary<int, List<Wall>>();
			this.GetWallColumnLinkInfo(ref result);
			return result;
		}

		private void GetWallColumnLinkInfo(ref Dictionary<int, List<Wall>> columnsGraph)
		{
			Level genLevel = this.m_uiApplication.ActiveUIDocument.ActiveView.GenLevel;
			Transaction transaction = new Transaction(this.m_document);
			transaction.Start("temp transaction");
			foreach (object obj in this.m_document.get_PlanTopology(genLevel).Circuits)
			{
				PlanCircuit planCircuit = (PlanCircuit)obj;
				if (!planCircuit.IsRoomLocated)
				{
					try
					{
						this.m_document.Create.NewRoom(null, planCircuit);
					}
					catch (Exception)
					{
					}
				}
			}
			List<Room> list = new List<Room>();
			this.GetRoomList(ref list);
			int num = 0;
			foreach (Room room in list)
			{
				foreach (IList<BoundarySegment> list2 in room.GetBoundarySegments(new SpatialElementBoundaryOptions()))
				{
					for (int i = 0; i < list2.Count; i++)
					{
						BoundarySegment segment = list2[i];
						if (segment.GetElement(this.m_document) != null && segment.GetElement(this.m_document).GetType() == typeof(FamilyInstance) && -2000100 == segment.GetElement(this.m_document).Category.Id.IntegerValue && (segment.GetElement(this.m_document) as FamilyInstance).Symbol.Family.Name.IndexOf("HYColumn") == -1)
						{
							if (!columnsGraph.ContainsKey(segment.GetElement(this.m_document).Id.IntegerValue))
							{
								List<Wall> value = new List<Wall>();
								if (this.AddWalls(list2, i, ref value))
								{
									columnsGraph.Add(segment.GetElement(this.m_document).Id.IntegerValue, value);
								}
							}
							else
							{
								List<Wall> list3 = columnsGraph[segment.GetElement(this.m_document).Id.IntegerValue];
								this.AddWalls(list2, i, ref list3);
							}
						}
					}
				}
				num++;
			}
			transaction.RollBack();
		}

		private bool AddWalls(IList<BoundarySegment> loop, int index, ref List<Wall> nodeWallList)
		{
			bool result = false;
			List<BoundarySegment> list = new List<BoundarySegment>();
			if (index == 0)
			{
				list.Add(loop[loop.Count - 1]);
				list.Add(loop[1]);
			}
			else if (index == loop.Count - 1)
			{
				list.Add(loop[index - 1]);
				list.Add(loop[0]);
			}
			else
			{
				list.Add(loop[index - 1]);
				list.Add(loop[index + 1]);
			}
			foreach (BoundarySegment segment in list)
			{
				if (segment.GetElement(this.m_document) != null && segment.GetElement(this.m_document).GetType() == typeof(Wall))
				{
					Wall wall = segment.GetElement(this.m_document) as Wall;
					if (nodeWallList.FindIndex((Wall value) => value.Id.IntegerValue == wall.Id.IntegerValue) == -1)
					{
						result = true;
						nodeWallList.Add(wall);
					}
				}
			}
			return result;
		}

		private void GetRoomList(ref List<Room> rooms)
		{
			foreach (Element element in new FilteredElementCollector(this.m_document, this.m_uiApplication.ActiveUIDocument.ActiveView.Id).OfCategory(BuiltInCategory.OST_Rooms).ToElements())
			{
				if (!(element.GetType() != typeof(Room)))
				{
					rooms.Add(element as Room);
				}
			}
		}

		private UIApplication m_uiApplication;

		protected Document m_document;
	}
}
